﻿Imports System
Imports System.Collections

Namespace System.Workflow.ComponentModel
    Friend MustInherit Class ActivityExecutionFilter
        Inherits ActivityExecutor
        Implements ISupportWorkflowChanges
        ' Methods
        Protected Sub New()
        End Sub

        Public Overrides Function Cancel(ByVal activity As Activity, ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Dim executor As ActivityExecutor = Me.NextActivityExecutorInChain(executionContext.Activity)
            If (Not TypeOf executor Is ActivityExecutionFilter AndAlso executionContext.Activity.HasPrimaryClosed) Then
                Return ActivityExecutionStatus.Closed
            End If
            Return executor.Cancel(activity, executionContext)
        End Function

        Public Overrides Function Compensate(ByVal activity As Activity, ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Return Me.NextActivityExecutorInChain(executionContext.Activity).Compensate(activity, executionContext)
        End Function

        Public Overrides Function Execute(ByVal activity As Activity, ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Return Me.NextActivityExecutorInChain(executionContext.Activity).Execute(activity, executionContext)
        End Function

        Public Overrides Function HandleFault(ByVal activity As Activity, ByVal executionContext As ActivityExecutionContext, ByVal exception As Exception) As ActivityExecutionStatus
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            If (exception Is Nothing) Then
                Throw New ArgumentNullException("exception")
            End If
            Dim executor As ActivityExecutor = Me.NextActivityExecutorInChain(executionContext.Activity)
            If (Not TypeOf executor Is ActivityExecutionFilter AndAlso executionContext.Activity.HasPrimaryClosed) Then
                Return ActivityExecutionStatus.Closed
            End If
            Return executor.HandleFault(activity, executionContext, exception)
        End Function

        Protected Function NextActivityExecutorInChain(ByVal activity As Activity) As ActivityExecutor
            If (activity Is Nothing) Then
                Throw New ArgumentNullException("activity")
            End If
            Dim executor As ActivityExecutor = Nothing
            Dim activityExecutors As IList = ActivityExecutors.GetActivityExecutors(activity)
            Dim index As Integer = activityExecutors.IndexOf(Me)
            If (index < (activityExecutors.Count - 1)) Then
                executor = DirectCast(activityExecutors.Item((index + 1)), ActivityExecutor)
            End If
            Return executor
        End Function

        Protected Function NextDynamicChangeExecutorInChain(ByVal activity As Activity) As ISupportWorkflowChanges
            Return [TryCast](Me.NextActivityExecutorInChain(activity),ISupportWorkflowChanges)
        End Function

        Public Overridable Sub OnActivityAdded(ByVal executionContext As ActivityExecutionContext, ByVal addedActivity As Activity)
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            If (addedActivity Is Nothing) Then
                Throw New ArgumentNullException("addedActivity")
            End If
            Me.NextDynamicChangeExecutorInChain(executionContext.Activity).OnActivityAdded(executionContext, addedActivity)
        End Sub

        Public Overridable Sub OnActivityRemoved(ByVal executionContext As ActivityExecutionContext, ByVal removedActivity As Activity)
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            If (removedActivity Is Nothing) Then
                Throw New ArgumentNullException("removedActivity")
            End If
            Me.NextDynamicChangeExecutorInChain(executionContext.Activity).OnActivityRemoved(executionContext, removedActivity)
        End Sub

        Public Overridable Sub OnWorkflowChangesCompleted(ByVal executionContext As ActivityExecutionContext)
            If (executionContext Is Nothing) Then
                Throw New ArgumentNullException("executionContext")
            End If
            Me.NextDynamicChangeExecutorInChain(executionContext.Activity).OnWorkflowChangesCompleted(executionContext)
        End Sub

    End Class
End Namespace

